package org.zoomdev.zoom.dao;

import org.zoomdev.zoom.common.expression.Symbol;

public interface Where<T extends Where> {

    /**
     * dao.ar("table").where("id",1).find()=>select * from table where id=?
     *
     * @param key
     * @param value
     * @return
     */
    T where(String key, Object value);

    /**
     * dao.ar("table").where("id",Symbol.GT,1).find()=>select * from table where id>?
     *
     * @param key
     * @param symbol
     * @param value
     * @return
     */
    T where(String key, Symbol symbol, Object value);

    /**
     * .where("id",2).where(new Condition(){
     * public void where(SqlBuilder where){
     * where.where("id",1).orWhere("name","张三")
     * }
     * })=>  id=? and (id = ? or name=?)
     *
     * @param condition
     * @return
     */
    T where(Condition condition);

    /**
     * where("id",Arrays.asList(1,2,3))=> where id in (?,?,?)
     *
     * @param key
     * @param values
     * @return
     */
    <E> T whereIn(String key, Iterable<E> values);


    <E> T whereIn(String key, Select select);

    /**
     * whereNotNull("name")=> where name is not null
     *
     * @param key
     * @return
     */
    T whereNotNull(String key);

    /**
     * whereNull("name")=> where name is null
     *
     * @param key
     * @return
     */
    T whereNull(String key);

    /**
     * like("name",Like.MATCH_LEFT,"张")=> name like ? => '张%'
     *
     * @param key
     * @param like
     * @param value
     * @return
     */
    T like(String key, Like like, Object value);

    /**
     * .where("id",2).orWhere(new Condition(){
     * public void where(SqlBuilder where){
     * where.where("id",1).orWhere("name","张三")
     * }
     * })=>  id=? or (id = ? or name=?)
     *
     * @param condition
     * @return
     */
    T orWhere(Condition condition);

    /**
     * where("id",1).orWhere("id",2)=> id=? or id=?
     *
     * @param key
     * @param value
     * @return
     */
    T orWhere(String key, Object value);


    T orLike(String key, Like like, Object value);


    T exists(Select select);

    /**
     * @author jzoom
     */
    enum Like {

        MATCH_BOTH("%%%s%%"),                //like '%{}%'
        MATCH_END("%%%s"),                //like '%{}'
        MATCH_START("%s%%");                //like '{}%'

        private final String format;

        Like(String format) {
            this.format = format;
        }

        public String toValue(Object value) {
            return String.format(format, value);
        }
    }


    interface Condition {
        void where(Where where);
    }

}
